﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.ComponentModel;
using System.Windows.Threading;

namespace Majoopic.Engine
{
    public class ProgressInformation : INotifyPropertyChanged
    {
        private object _TotalImagesFoundLocker = new object();
        private int _TotalImagesFound = 0;
        public int TotalImagesFound
        {
            get
            {
                lock (_TotalImagesFoundLocker)
                {
                    return this._TotalImagesFound;
                }
            }
            set
            {
                lock (this._TotalImagesFoundLocker)
                {
                    this._TotalImagesFound = value;
                }
                this.OnProgressChanged("TotalImagesFound");
            }
        }

        private object _NumberImagesScanedLocker = new object();
        private int _NumberImagesScaned = 0;
        public int NumberImagesScaned
        {
            get
            {
                lock (this._NumberImagesScanedLocker)
                {
                    return this._NumberImagesScaned;
                }
            }
            set
            {
                lock (this._NumberImagesScanedLocker)
                {
                    this._NumberImagesScaned = value;
                }
                this.OnProgressChanged("NumberImagesScaned");
            }
        }

        private object _NumberImagesScanedFailedLocker = new object();
        private int _NumberImagesScanFailed = 0;
        public int NumberImagesScanFailed
        {
            get
            {
                lock (this._NumberImagesScanedFailedLocker)
                {
                    return this._NumberImagesScanFailed;
                }
            }
            set
            {
                lock (this._NumberImagesScanedFailedLocker)
                {
                    this._NumberImagesScanFailed = value;
                }
                this.OnProgressChanged("NumberImagesScanFailed");
            }
        }

        private object _TotalImagesToSaveLocker = new object();
        private int _TotalImagesToSave = 0;
        public int TotalImagesToSave
        {
            get
            {
                lock (this._TotalImagesToSaveLocker)
                {
                    return this._TotalImagesToSave;
                }
            }
            set
            {
                lock (this._TotalImagesToSaveLocker)
                {
                    this._TotalImagesToSave = value;
                }
                this.OnProgressChanged("TotalImagesToSave");
            }
        }

        private object _NumberImagesSavedLocker = new object();
        private int _NumberImagesSaved = 0;
        public int NumberImagesSaved
        {
            get
            {
                lock (this._NumberImagesSavedLocker)
                {
                    return this._NumberImagesSaved;
                }
            }
            set
            {
                lock (this._NumberImagesSavedLocker)
                {
                    this._NumberImagesSaved = value;
                }
                this.OnProgressChanged("NumberImagesSaved");
            }
        }

        private object _NumberImagesSaveFailedLocker = new object();
        private int _NumberImagesSaveFailed = 0;
        public int NumberImagesSaveFailed
        {
            get
            {
                lock (this._NumberImagesSaveFailedLocker)
                {
                    return this._NumberImagesSaveFailed;
                }
            }
            set
            {
                lock (this._NumberImagesSaveFailedLocker)
                {
                    this._NumberImagesSaveFailed = value;
                }
                this.OnProgressChanged("NumberImagesSaveFailed");
            }
        }

        private object _TotalDirectoryScanLocker = new object();
        private int _TotalDirectoryScan = 0;
        public int TotalDirectoryScan
        {
            get
            {
                lock (this._TotalDirectoryScanLocker)
                {
                    return this._TotalDirectoryScan;
                }
            }
            set
            {
                lock (this._TotalDirectoryScanLocker)
                {
                    this._TotalDirectoryScan = value;
                }
                this.OnProgressChanged("TotalDirectoryScan");
            }
        }

        private object _IsScanDirectoryLocker = new object();
        private bool _IsScanDirectory = false;
        public bool IsScanDirectory
        {
            get
            {
                lock (this._IsScanDirectoryLocker)
                {
                    return this._IsScanDirectory;
                }
            }
            set
            {
                lock (this._IsScanDirectoryLocker)
                {
                    this._IsScanDirectory = value;
                }
                this.OnProgressChanged("IsScanDirectory");
            }
        }

        private event PropertyChangedEventHandler _PropertyChanged;
        /// <summary>
        /// Fire when a change occur
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged
        {
            add { this._PropertyChanged += value; }
            remove { this._PropertyChanged -= value; }
        }
        
        private void OnProgressChanged(string propertyName)
        {
            if (this._PropertyChanged != null)
            {
                if (this._UIDispatcher != null && !this._UIDispatcher.CheckAccess())
                {
                    this._UIDispatcher.BeginInvoke(new Action(() => this.OnProgressChanged(propertyName)));
                }
                this._PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private Dispatcher _UIDispatcher;

        /// <summary>
        /// Constructor
        /// </summary>
        public ProgressInformation()
        {
            
        }

        public ProgressInformation(Dispatcher uiDispatcher)
        {
            this._UIDispatcher = uiDispatcher;
        }

        public void IncrementTotalImagesFound(int value = 1)
        {            
            this.TotalImagesFound += value;
        }

        public void IncrementNumberImagesScaned(int value = 1)
        {
            this.NumberImagesScaned += value;
        }

        public void IncrementNumberImagesSaved(int value = 1)
        {
            this.NumberImagesSaved += value;
        }

        public void IncrementTotalImagesToSave(int value = 1)
        {
            this.TotalImagesToSave += value;
        }

        public void IncrementNumberImagesSaveFailed(int value = 1)
        {
            this.NumberImagesSaveFailed += value;
        }

        public void IncrementNumberImagesScanFailed(int value = 1)
        {
            this.NumberImagesScanFailed += value;
        }

        public void IncrementTotalDirectoryScan(int value=1)
        {
            this.TotalDirectoryScan += value;
        }
    }

    public class ProgressInformationEventArgs : EventArgs
    {
        public ProgressInformation Information
        {
            get;
            set;
        }

        public ProgressInformationEventArgs()
            : base()
        {
           
        }

        public ProgressInformationEventArgs(ProgressInformation progressInformation)
            : base()
        {
            this.Information = progressInformation;
        }
    }
}
